package com.zh.demo04.login;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.Map;

/**
 * 前台用户(即Web端) Form/Phone登录 数据库获取用户信息
 */
@AllArgsConstructor
@Slf4j
public class WebUserDetailsService implements UserDetailsService {

    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {

        String[] user;
        if (isPhoneNumber(account)) {
            log.info("{}【有人Phone登录 Web端】：phone = {}", Thread.currentThread().getId(), account);

            //数据库查询登录账号数据. 实际中从数据库查询.
            if (!phone_table.containsKey(account)) throw new UsernameNotFoundException("手机号未注册");

            user = phone_table.get(account);
        } else {
            log.info("{}【有人Form登录 Web端】：username = {}", Thread.currentThread().getId(), account);

            //数据库查询登录账号数据. 实际中从数据库查询.
            if (!user_table.containsKey(account)) throw new UsernameNotFoundException("账号不存在");

            user = user_table.get(account);
        }

        //生成Spring Security中登录用户的信息
        return new User(user[0], passwordEncoder.encode(user[1]), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_" + user[2]));
    }

    //模拟数据库中的用户表
    static Map<String, String[]> user_table = Map.of(
            "apple", new String[]{"apple", "123456", "USER"},
            "banana", new String[]{"banana", "123456", "USER,VIP1"}
    );
    //模拟数据库中的用户表
    static Map<String, String[]> phone_table = Map.of(
            "16622220000", new String[]{"apple", "123456", "USER"},
            "18866660000", new String[]{"banana", "123456", "USER,VIP1"}
    );

    private boolean isPhoneNumber(String str) {
        final String PHONE_REGEXP = "^1\\d{10}$";
        return str.matches(PHONE_REGEXP);
    }


}
